<script lang="ts" setup>
import {ref, watch, computed, onMounted, onUnmounted, nextTick} from 'vue'

const props = defineProps({
  enterAction: {
    type: Object,
    required: true
  }
})

// 响应式数据
const inputText = ref('')
const outputText = ref('')
const fileName = ref('')
const isLoading = ref(false)
const error = ref('')
const successMessage = ref('')
const isDragOver = ref(false)

// 帮助标签页数据
const activeHelpTab = ref('usage')
const helpTabs = ref([
  {key: 'usage', title: '💡 使用说明'},
  {key: 'static', title: '📁 静态资源代理'},
  {key: 'proxy', title: '🔄 接口转发'},
  {key: 'balance', title: '⚖️ 负载均衡'}
])

// 查找替换功能数据
const showFindReplace = ref(false)
const showReplaceSection = ref(false) // 控制替换区域的显示
const findText = ref('')
const replaceText = ref('')
const caseSensitive = ref(false)
const useRegex = ref(false)
const currentMatches = ref([])
const currentMatchIndex = ref(-1)

// 文本区域引用和高亮相关
const textareaRef = ref(null)
const highlightPositions = ref([])

// 字符宽度缓存
let charWidthCache = null
let lastFontSize = null

// 计算属性：是否有输出内容
const hasOutput = computed(() => outputText.value.trim() !== '')

// Nginx配置格式化函数
const formatNginxConfig = (config: string): string => {
  if (!config || config.trim() === '') {
    return ''
  }

  let formatted = ''
  let indentLevel = 0
  const indentSize = 4 // 缩进空格数

  // 移除多余的空白字符并按行分割
  const lines = config
      .replace(/\r\n/g, '\n')
      .replace(/\r/g, '\n')
      .split('\n')
      .map(line => line.trim())
      .filter(line => line !== '')

  for (let i = 0; i < lines.length; i++) {
    const line = lines[i]

    // 跳过注释行，但保持格式
    if (line.startsWith('#')) {
      formatted += ' '.repeat(indentLevel * indentSize) + line + '\n'
      continue
    }

    // 处理闭合大括号
    if (line === '}' || line.endsWith('}')) {
      indentLevel = Math.max(0, indentLevel - 1)
      formatted += ' '.repeat(indentLevel * indentSize) + line + '\n'
      continue
    }

    // 添加当前行
    formatted += ' '.repeat(indentLevel * indentSize) + line + '\n'

    // 处理开放大括号
    if (line.endsWith('{')) {
      indentLevel++
    }
  }

  return formatted.trim()
}

// 格式化处理函数
const handleFormat = () => {
  if (!inputText.value.trim()) {
    error.value = '请输入Nginx配置内容'
    return
  }

  isLoading.value = true
  error.value = ''

  try {
    // 模拟异步处理
    setTimeout(() => {
      outputText.value = formatNginxConfig(inputText.value)
      isLoading.value = false

      if (!outputText.value) {
        error.value = '格式化失败，请检查配置内容'
      }
    }, 100)
  } catch (err) {
    error.value = '格式化过程中出现错误：' + (err as Error).message
    isLoading.value = false
  }
}

// 清空内容
const handleClear = () => {
  inputText.value = ''
  outputText.value = ''
  fileName.value = ''
  error.value = ''
}

// 复制到剪贴板
const handleCopy = async () => {
  try {
    await navigator.clipboard.writeText(outputText.value)
    successMessage.value = '✅ 已复制到剪贴板'
    error.value = ''

    // 3秒后清除提示
    setTimeout(() => {
      successMessage.value = ''
    }, 3000)

    // 如果在utools环境中，也显示通知
    if (window.utools && window.utools.showNotification) {
      window.utools.showNotification('已复制到剪贴板')
    }
  } catch (err) {
    error.value = '复制失败，请手动复制'
    successMessage.value = ''
  }
}

// 保存为文件
const handleSave = () => {
  try {
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
    const defaultName = fileName.value || `nginx_formatted_${timestamp}.conf`

    // 使用services保存文件
    const outputPath = window.services.writeNginxFile(outputText.value, defaultName)

    if (outputPath) {
      successMessage.value = '✅ 文件保存成功'
      error.value = ''

      // 3秒后清除提示
      setTimeout(() => {
        successMessage.value = ''
      }, 3000)

      // 如果在utools环境中，显示通知并打开文件夹
      if (window.utools) {
        if (window.utools.showNotification) {
          window.utools.showNotification('文件保存成功')
        }
        if (window.utools.shellShowItemInFolder) {
          window.utools.shellShowItemInFolder(outputPath)
        }
      }
    }
  } catch (err) {
    error.value = '文件保存失败：' + (err as Error).message
    successMessage.value = ''
  }
}

// 拖拽事件处理
const handleDragEnter = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  isDragOver.value = true
}

const handleDragOver = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
}

const handleDragLeave = (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  // 只有当离开整个拖拽区域时才设置为false
  if (!e.currentTarget?.contains(e.relatedTarget as Node)) {
    isDragOver.value = false
  }
}

const handleDrop = async (e: DragEvent) => {
  e.preventDefault()
  e.stopPropagation()
  isDragOver.value = false

  const files = e.dataTransfer?.files
  if (!files || files.length === 0) {
    return
  }

  const file = files[0]

  // 检查文件类型
  const allowedTypes = ['.conf', '.txt', '.config']
  const fileExtension = file.name.toLowerCase().substring(file.name.lastIndexOf('.'))

  if (!allowedTypes.includes(fileExtension)) {
    error.value = '请选择 .conf、.txt 或 .config 文件'
    successMessage.value = ''
    return
  }

  try {
    const text = await file.text()
    inputText.value = text
    fileName.value = file.name
    error.value = ''
    successMessage.value = '✅ 文件加载成功'

    // 3秒后清除提示
    setTimeout(() => {
      successMessage.value = ''
    }, 3000)

    // 自动格式化
    handleFormat()
  } catch (err) {
    error.value = '读取文件失败：' + (err as Error).message
    successMessage.value = ''
  }
}

// 粘贴事件处理
const handlePaste = async (e: ClipboardEvent) => {
  // 检查剪贴板中是否有文件
  const items = e.clipboardData?.items
  if (!items) return

  for (let i = 0; i < items.length; i++) {
    const item = items[i]

    // 如果是文件类型
    if (item.kind === 'file') {
      e.preventDefault()
      const file = item.getAsFile()
      if (!file) continue

      // 检查文件类型
      const allowedTypes = ['.conf', '.txt', '.config']
      const fileExtension = file.name.toLowerCase().substring(file.name.lastIndexOf('.'))

      if (!allowedTypes.includes(fileExtension)) {
        error.value = '请粘贴 .conf、.txt 或 .config 文件'
        successMessage.value = ''
        return
      }

      try {
        const text = await file.text()
        inputText.value = text
        fileName.value = file.name
        error.value = ''
        successMessage.value = '✅ 文件粘贴成功'

        // 3秒后清除提示
        setTimeout(() => {
          successMessage.value = ''
        }, 3000)

        // 自动格式化
        handleFormat()
        return
      } catch (err) {
        error.value = '读取文件失败：' + (err as Error).message
        successMessage.value = ''
        return
      }
    }

    // 如果是文本类型，检查是否像配置文件内容
    if (item.kind === 'string' && item.type === 'text/plain') {
      item.getAsString((text) => {
        // 简单检测是否像 Nginx 配置内容（包含常见关键字）
        const nginxKeywords = ['server', 'location', 'listen', 'root', 'index', 'proxy_pass', 'upstream']
        const hasNginxKeywords = nginxKeywords.some(keyword =>
            text.toLowerCase().includes(keyword)
        )

        // 如果包含 Nginx 关键字或者文本较长（可能是配置文件），自动格式化
        if (hasNginxKeywords || text.length > 100) {
          e.preventDefault()
          inputText.value = text
          error.value = ''
          successMessage.value = '✅ 内容粘贴成功'

          // 3秒后清除提示
          setTimeout(() => {
            successMessage.value = ''
          }, 3000)

          // 自动格式化
          handleFormat()
        }
      })
    }
  }
}

// 监听进入动作
watch(() => props.enterAction, (enterAction) => {
  if (enterAction.type === "files" && enterAction.payload && enterAction.payload.length > 0) {
    // 文件拖入或选择文件进入
    const file = enterAction.payload[0]
    fileName.value = file.name

    try {
      const content = window.services.readFile(file.path)
      inputText.value = content
      // 自动格式化
      handleFormat()
    } catch (err) {
      error.value = '读取文件失败：' + (err as Error).message
    }
  }
}, {
  immediate: true
})

// 复制配置示例
const copyConfig = async (configType: string) => {
  // 定义配置示例内容
  const configs = {
    static: `server {
    listen 80;
    server_name example.com;

    location /static/ {
        # 静态资源所在目录
        alias /path/to/your/static/files/;

        # 启用自动索引（可选）
        # autoindex on;
        # 设置缓存头
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}`,
    proxy: `server {
    listen 80;
    server_name api.example.com;
    
    location /api/ {
        proxy_pass http://backend-server:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}`,
    balance: `upstream backend {
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 backup;
}

server {
    listen 80;
    server_name lb.example.com;
    
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}`
  }

  try {
    const configText = configs[configType as keyof typeof configs]
    if (configText) {
      await navigator.clipboard.writeText(configText)
      successMessage.value = '✅ 配置已复制到剪贴板'
      error.value = ''

      // 3秒后清除提示
      setTimeout(() => {
        successMessage.value = ''
      }, 3000)

      // 如果在utools环境中，也显示通知
      if (window.utools && window.utools.showNotification) {
        window.utools.showNotification('配置已复制到剪贴板')
      }
    }
  } catch (err) {
    error.value = '复制失败，请手动复制'
    successMessage.value = ''
  }
}

/**
 * 切换查找替换面板的显示状态
 */
const toggleFindReplace = () => {
  showFindReplace.value = !showFindReplace.value
  if (!showFindReplace.value) {
    // 关闭时清空搜索结果
    currentMatches.value = []
    currentMatchIndex.value = -1
    showReplaceSection.value = false // 关闭面板时也隐藏替换区域
  }
}

/**
 * 切换替换区域的显示状态
 */
const toggleReplaceSection = () => {
  showReplaceSection.value = !showReplaceSection.value
}

/**
 * 获取当前活动的文本内容（只针对输入区域）
 */
const getCurrentText = () => {
  return inputText.value
}

/**
 * 设置当前活动的文本内容（只针对输入区域）
 */
const setCurrentText = (text: string) => {
  inputText.value = text
}

/**
 * 执行查找操作
 */
const performFind = () => {
  if (!findText.value) {
    currentMatches.value = []
    currentMatchIndex.value = -1
    return
  }

  const text = getCurrentText()
  const searchText = findText.value
  const matches = []

  try {
    if (useRegex.value) {
      // 正则表达式查找
      const flags = caseSensitive.value ? 'g' : 'gi'
      const regex = new RegExp(searchText, flags)
      let match
      while ((match = regex.exec(text)) !== null) {
        matches.push({
          index: match.index,
          length: match[0].length,
          text: match[0]
        })
        // 防止无限循环
        if (match[0].length === 0) {
          regex.lastIndex++
        }
      }
    } else {
      // 普通文本查找
      const searchStr = caseSensitive.value ? searchText : searchText.toLowerCase()
      const textStr = caseSensitive.value ? text : text.toLowerCase()
      
      let index = 0
      while ((index = textStr.indexOf(searchStr, index)) !== -1) {
        matches.push({
          index: index,
          length: searchText.length,
          text: text.substr(index, searchText.length)
        })
        index += searchText.length
      }
    }

    currentMatches.value = matches
    currentMatchIndex.value = matches.length > 0 ? 0 : -1
  } catch (err) {
    error.value = '查找失败：' + (err as Error).message
    currentMatches.value = []
    currentMatchIndex.value = -1
  }
}

/**
 * 跳转到下一个匹配项
 */
const findNext = () => {
  if (currentMatches.value.length === 0) {
    performFind()
    return
  }
  
  if (currentMatchIndex.value < currentMatches.value.length - 1) {
    currentMatchIndex.value++
  } else {
    currentMatchIndex.value = 0 // 循环到第一个
  }
  
  // 滚动到当前匹配项
  nextTick(() => {
    scrollToCurrentMatch()
  })
}

/**
 * 跳转到上一个匹配项
 */
const findPrevious = () => {
  if (currentMatches.value.length === 0) {
    performFind()
    return
  }
  
  if (currentMatchIndex.value > 0) {
    currentMatchIndex.value--
  } else {
    currentMatchIndex.value = currentMatches.value.length - 1 // 循环到最后一个
  }
  
  // 滚动到当前匹配项
  nextTick(() => {
    scrollToCurrentMatch()
  })
}

/**
 * 替换当前匹配项
 */
const replaceCurrent = () => {
  if (currentMatches.value.length === 0 || currentMatchIndex.value === -1) {
    return
  }

  const text = getCurrentText()
  const match = currentMatches.value[currentMatchIndex.value]
  
  // 执行替换
  const newText = text.substring(0, match.index) + 
                  replaceText.value + 
                  text.substring(match.index + match.length)
  
  setCurrentText(newText)
  
  // 更新匹配项索引（因为文本长度可能改变）
  const lengthDiff = replaceText.value.length - match.length
  for (let i = currentMatchIndex.value + 1; i < currentMatches.value.length; i++) {
    currentMatches.value[i].index += lengthDiff
  }
  
  // 移除当前匹配项
  currentMatches.value.splice(currentMatchIndex.value, 1)
  
  // 调整当前索引
  if (currentMatchIndex.value >= currentMatches.value.length) {
    currentMatchIndex.value = currentMatches.value.length - 1
  }
  
  successMessage.value = '✅ 替换成功'
  setTimeout(() => {
    successMessage.value = ''
  }, 2000)
}

/**
 * 替换所有匹配项
 */
const replaceAll = () => {
  if (currentMatches.value.length === 0) {
    return
  }

  let text = getCurrentText()
  const replacements = currentMatches.value.length
  
  // 从后往前替换，避免索引偏移问题
  for (let i = currentMatches.value.length - 1; i >= 0; i--) {
    const match = currentMatches.value[i]
    text = text.substring(0, match.index) + 
           replaceText.value + 
           text.substring(match.index + match.length)
  }
  
  setCurrentText(text)
  
  // 清空匹配项
  currentMatches.value = []
  currentMatchIndex.value = -1
  
  successMessage.value = `✅ 已替换 ${replacements} 个匹配项`
  setTimeout(() => {
    successMessage.value = ''
  }, 3000)
}



// 监听查找文本变化，自动执行查找
watch(findText, () => {
  if (findText.value) {
    performFind()
  } else {
    currentMatches.value = []
    currentMatchIndex.value = -1
  }
})

// 监听查找选项变化，重新执行查找
watch([caseSensitive, useRegex], () => {
  if (findText.value) {
    performFind()
  }
})

/**
 * 计算高亮标记的样式位置
 */
const getHighlightStyle = (match) => {
  if (!textareaRef.value) return {}
  
  const textarea = textareaRef.value
  const text = textarea.value
  
  // 计算匹配文本在textarea中的位置
  const beforeText = text.substring(0, match.index)
  const lines = beforeText.split('\n')
  const lineNumber = lines.length - 1
  const columnNumber = lines[lines.length - 1].length
  
  // 获取textarea的样式信息
  const computedStyle = window.getComputedStyle(textarea)
  const fontSize = parseFloat(computedStyle.fontSize) || 13
  const lineHeightValue = computedStyle.lineHeight
  
  // 计算实际行高
  let lineHeight
  if (lineHeightValue === 'normal' || lineHeightValue.includes('%')) {
    lineHeight = fontSize * 1.5 // 默认line-height: 1.5
  } else if (lineHeightValue.includes('px')) {
    lineHeight = parseFloat(lineHeightValue)
  } else {
    lineHeight = fontSize * parseFloat(lineHeightValue)
  }
  
  // 使用Canvas精确测量字符宽度（带缓存）
  let charWidth
  if (charWidthCache === null || lastFontSize !== fontSize) {
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    ctx.font = `${fontSize}px Consolas, Monaco, 'Courier New', monospace`
    charWidth = ctx.measureText('M').width // 使用M字符作为等宽字体的标准宽度
    charWidthCache = charWidth
    lastFontSize = fontSize
  } else {
    charWidth = charWidthCache
  }
  
  // 计算位置（高亮层已经考虑了padding偏移）
  const top = lineNumber * lineHeight - textarea.scrollTop
  const left = columnNumber * charWidth - textarea.scrollLeft
  
  // 计算高亮区域的宽度
  const matchText = match.text
  const width = matchText.length * charWidth
  
  return {
    position: 'absolute',
    top: `${top}px`,
    left: `${left}px`,
    width: `${width}px`,
    height: `${lineHeight}px`,
    pointerEvents: 'none'
  }
}

/**
 * 更新高亮位置（当textarea滚动时）
 */
const updateHighlightPosition = () => {
  // 触发重新计算高亮位置
  if (currentMatches.value.length > 0) {
    // 强制重新渲染高亮
    const matches = [...currentMatches.value]
    currentMatches.value = []
    nextTick(() => {
      currentMatches.value = matches
    })
  }
}

/**
 * 处理textarea输入事件
 */
const onTextareaInput = () => {
  // 当文本改变时，重新执行查找
  if (findText.value) {
    performFind()
  }
}

/**
 * 滚动到当前匹配项
 */
const scrollToCurrentMatch = () => {
  if (currentMatchIndex.value >= 0 && currentMatches.value.length > 0 && textareaRef.value) {
    const textarea = textareaRef.value
    const match = currentMatches.value[currentMatchIndex.value]
    
    // 设置textarea的选择范围
    textarea.focus()
    textarea.setSelectionRange(match.index, match.index + match.length)
    
    // 滚动到选中位置
    const text = textarea.value
    const beforeText = text.substring(0, match.index)
    const lines = beforeText.split('\n')
    const lineNumber = lines.length - 1
    
    const computedStyle = window.getComputedStyle(textarea)
    const lineHeight = parseFloat(computedStyle.lineHeight) || 20
    
    // 计算滚动位置
    const scrollTop = Math.max(0, lineNumber * lineHeight - textarea.clientHeight / 2)
    textarea.scrollTop = scrollTop
  }
}

/**
 * 处理键盘快捷键
 */
const handleKeydown = (e: KeyboardEvent) => {
  // Ctrl+F 打开查找替换面板
  if (e.ctrlKey && e.key === 'f') {
    e.preventDefault()
    showFindReplace.value = true
    // 延迟聚焦到查找输入框
    setTimeout(() => {
      const findInput = document.querySelector('.find-input') as HTMLInputElement
      if (findInput) {
        findInput.focus()
        findInput.select()
      }
    }, 100)
  }
  // Esc 关闭查找替换面板
  else if (e.key === 'Escape' && showFindReplace.value) {
    showFindReplace.value = false
  }
}
 
 // 组件挂载时添加键盘事件监听
 onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
})
</script>

<template>
  <div class="nginx-format">
    <div class="header">
      <h1>🔧 Nginx配置格式化工具</h1>
      <p class="description">支持文本输入和文件上传两种方式，快速格式化您的Nginx配置文件</p>
    </div>



    <div class="content">
      <!-- 输入区域 -->
      <div class="input-section">
        <div class="section-header">
          <h3>📝 输入配置</h3>
          <div class="header-actions">
            <div class="file-info" v-if="fileName">
              <span class="file-name">{{ fileName }}</span>
            </div>
            <button @click="toggleFindReplace" class="btn-small" title="查找替换 (Ctrl+F)">
              🔍 查找替换
            </button>
          </div>
        </div>

        <!-- 文本输入区域容器 -->
        <div class="textarea-container">
          <!-- 高亮覆盖层 -->
          <div class="highlight-overlay" v-if="currentMatches.length > 0">
            <div 
              v-for="(match, index) in currentMatches" 
              :key="index"
              :class="['highlight-mark', { 'current-match': index === currentMatchIndex }]"
              :style="getHighlightStyle(match)"
            ></div>
          </div>
          
          <!-- 文本输入框 -->
          <textarea 
            ref="textareaRef"
            v-model="inputText" 
            placeholder="请输入Nginx配置内容，或拖拽.conf文件到此处，也可以复制文件后Ctrl+V粘贴..." 
            :class="['config-textarea', { 'drag-over': isDragOver }]" 
            rows="12" 
            @dragenter="handleDragEnter" 
            @dragover="handleDragOver" 
            @dragleave="handleDragLeave" 
            @drop="handleDrop" 
            @paste="handlePaste"
            @scroll="updateHighlightPosition"
            @input="onTextareaInput"
          ></textarea>
        </div>

        <div class="input-actions">
          <button @click="handleFormat" :disabled="isLoading || !inputText.trim()" class="btn">
            <span v-if="isLoading">⏳ 格式化中...</span>
            <span v-else>✨ 格式化</span>
          </button>
          <button @click="handleClear" class="btn">🗑️ 清空</button>
        </div>
      </div>

      <!-- 输出区域 -->
      <div class="output-section">
        <div class="section-header">
          <h3>📋 格式化结果</h3>
        </div>

        <textarea v-model="outputText" readonly placeholder="格式化后的配置将显示在这里..." class="config-textarea output" rows="12"></textarea>

        <div class="output-actions" v-if="hasOutput">
          <button @click="handleCopy" class="btn">📋 复制</button>
          <button @click="handleSave" class="btn">💾 保存</button>
        </div>
      </div>
    </div>

    <!-- 错误提示 -->
    <div v-if="error" class="error-message">
      ⚠️ {{ error }}
    </div>

    <!-- 成功提示 -->
    <div v-if="successMessage" class="success-message">
      {{ successMessage }}
    </div>

    <!-- 查找替换面板 -->
    <div v-if="showFindReplace" class="find-replace-panel">
      <div class="find-replace-content">
        <!-- 面板头部 -->
        <div class="panel-header">
          <div class="header-left">
            <span class="panel-title">🔍 查找</span>
            <button @click="toggleReplaceSection" class="toggle-replace-btn" :title="showReplaceSection ? '隐藏替换' : '显示替换'">
              {{ showReplaceSection ? '▼' : '▶' }} 替换
            </button>
          </div>
          <div class="header-center">
            <label class="checkbox-item">
              <input type="checkbox" v-model="caseSensitive">
              <span>Aa</span>
            </label>
            <label class="checkbox-item">
              <input type="checkbox" v-model="useRegex">
              <span>.*</span>
            </label>
          </div>
          <button @click="toggleFindReplace" class="close-btn" title="关闭">✕</button>
        </div>

        <!-- 查找输入框 -->
        <div class="find-input-group">
          <div class="input-with-buttons">
            <input 
              type="text" 
              v-model="findText" 
              placeholder="输入要查找的内容..." 
              class="find-input"
              @keyup.enter="findNext"
            >
            <div class="find-buttons">
              <button @click="findPrevious" :disabled="currentMatches.length === 0" class="btn-mini" title="上一个">↑</button>
              <button @click="findNext" :disabled="currentMatches.length === 0" class="btn-mini" title="下一个">↓</button>
            </div>
          </div>
          <div class="match-info" v-if="findText">
            <span v-if="currentMatches.length > 0">
              {{ currentMatchIndex + 1 }} / {{ currentMatches.length }}
            </span>
            <span v-else>无匹配项</span>
          </div>
        </div>

        <!-- 替换输入框 (条件显示) -->
        <div v-if="showReplaceSection" class="replace-input-group">
          <div class="input-with-buttons">
            <input 
              type="text" 
              v-model="replaceText" 
              placeholder="输入替换内容..." 
              class="replace-input"
              @keyup.enter="replaceCurrent"
            >
            <div class="replace-buttons">
              <button @click="replaceCurrent" :disabled="currentMatches.length === 0" class="btn-mini" title="替换当前">替换</button>
              <button @click="replaceAll" :disabled="currentMatches.length === 0" class="btn-mini" title="全部替换">全部</button>
            </div>
          </div>
        </div>


      </div>
    </div>

    <!-- 帮助和示例区域 -->
    <div class="help-section">
      <div class="help-tabs">
        <button v-for="tab in helpTabs" :key="tab.key" :class="['help-tab', { active: activeHelpTab === tab.key }]" @click="activeHelpTab = tab.key">
          {{ tab.title }}
        </button>
      </div>

      <div class="help-content">
        <!-- 使用说明 -->
        <div v-if="activeHelpTab === 'usage'" class="help-panel">
          <ul>
            <li>支持直接粘贴Nginx配置内容进行格式化</li>
            <li>支持拖拽或选择.conf文件进行格式化</li>
            <li>支持复制文件后Ctrl+V粘贴</li>
            <li>自动处理缩进和代码块结构</li>
            <li>保留注释内容和格式</li>
          </ul>
        </div>

        <!-- 静态资源代理 -->
        <div v-if="activeHelpTab === 'static'" class="help-panel">
          <div class="config-container">
            <pre class="config-example">server {
    listen 80;
    server_name example.com;

    location /static/ {
        # 静态资源所在目录
        alias /path/to/your/static/files/;

        # 启用自动索引（可选）
        # autoindex on;
        # 设置缓存头
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}</pre>
            <button class="copy-btn" @click="copyConfig('static')" title="复制配置">📋</button>
          </div>
        </div>

        <!-- 接口转发 -->
        <div v-if="activeHelpTab === 'proxy'" class="help-panel">
          <div class="config-container">
            <pre class="config-example">server {
    listen 80;
    server_name api.example.com;
    
    location /api/ {
        proxy_pass http://backend-server:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}</pre>
            <button class="copy-btn" @click="copyConfig('proxy')" title="复制配置">📋</button>
          </div>
        </div>

        <!-- 负载均衡 -->
        <div v-if="activeHelpTab === 'balance'" class="help-panel">
          <div class="config-container">
            <pre class="config-example">upstream backend {
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 backup;
}

server {
    listen 80;
    server_name lb.example.com;
    
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}</pre>
            <button class="copy-btn" @click="copyConfig('balance')" title="复制配置">📋</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.nginx-format {
  display: flex;
  flex-direction: column;
  height: 100vh;
  min-height: 600px;
  padding: 10px 20px;
  width: 100%;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  box-sizing: border-box;
}

.header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  height: 50px;
  flex-shrink: 0;
  margin-bottom: 10px;
}

.header h1 {
  color: #2c3e50;
  margin: 0;
  font-size: 18px;
}

.description {
  color: #7f8c8d;
  margin: 0;
  font-size: 12px;
}

.content {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  flex: 1;
  min-height: 0;
}

.input-section, .output-section {
  border: 1px solid #e1e8ed;
  border-radius: 8px;
  padding: 16px;
  background: #fafbfc;
  display: flex;
  flex-direction: column;
  min-height: 300px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.section-header h3 {
  margin: 0;
  color: #2c3e50;
  font-size: 14px;
}

.file-info {
  background: #e8f4fd;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
}

.file-name {
  color: #1976d2;
  font-weight: 500;
}

.config-textarea {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid #d1d9e0;
  border-radius: 6px;
  padding: 12px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.5;
  resize: none;
  background: transparent;
  transition: all 0.3s ease;
  flex: 1;
  min-height: 200px;
  position: relative;
  z-index: 2;
}

.config-textarea.drag-over {
  border-color: #3498db;
  background: #f0f8ff;
  box-shadow: 0 0 10px rgba(52, 152, 219, 0.3);
}

.config-textarea:focus {
  outline: none;
  border-color: #4285f4;
  box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.2);
}

.config-textarea.output {
  background: #f8f9fa;
  color: #2c3e50;
}

.input-actions, .output-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
  flex-shrink: 0;
}

.btn {
  padding: 4px 12px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  transition: all 0.2s;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn {
  background: #4285f4;
  color: white;
}

.btn:hover:not(:disabled) {
  background: #3367d6;
}

.btn:disabled {
  background: #f1f3f4;
  color: #5f6368;
}

.error-message {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(255, 255, 255, 0.95);
  color: #e74c3c;
  padding: 12px 20px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #e74c3c;
  z-index: 1000;
  font-size: 14px;
  font-weight: 500;
  backdrop-filter: blur(10px);
  animation: slideDown 0.3s ease-out;
}

.success-message {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(255, 255, 255, 0.95);
  color: #27ae60;
  padding: 12px 20px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #27ae60;
  z-index: 1000;
  font-size: 14px;
  font-weight: 500;
  backdrop-filter: blur(10px);
  animation: slideDown 0.3s ease-out;
}



.help-section {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 10px 16px 16px 16px;
  border-left: 4px solid #4285f4;
  height: 120px;
  flex-shrink: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: row;
  gap: 12px;
}

.help-tabs {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex-shrink: 0;
  min-width: 80px;
}

.help-tab {
  background: #e9ecef;
  border: none;
  padding: 3px 6px;
  border-radius: 3px;
  font-size: 10px;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #6c757d;
  white-space: nowrap;
}

.help-tab:hover {
  background: #dee2e6;
  color: #495057;
}

.help-tab.active {
  background: #4285f4;
  color: white;
}

.help-content {
  flex: 1;
  overflow-y: auto;
  min-width: 0;
}

.help-panel ul {
  margin: 0;
  padding-left: 20px;
}

.help-panel li {
  color: #5f6368;
  font-size: 13px;
  margin-bottom: 4px;
}

.config-example {
  background: #2d3748;
  color: #e2e8f0;
  padding: 12px;
  border-radius: 6px;
  font-size: 11px;
  line-height: 1.4;
  margin: 0;
  overflow-x: auto;
  white-space: pre;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}

.config-example::-webkit-scrollbar {
  height: 6px;
}

.config-example::-webkit-scrollbar-track {
  background: #4a5568;
  border-radius: 3px;
}

.config-example::-webkit-scrollbar-thumb {
  background: #718096;
  border-radius: 3px;
}

.config-example::-webkit-scrollbar-thumb:hover {
  background: #a0aec0;
}

/* 配置容器样式 */
.config-container {
  position: relative;
}

/* 复制按钮样式 */
.copy-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  background: #4a5568;
  color: #e2e8f0;
  border: none;
  border-radius: 4px;
  padding: 4px 6px;
  font-size: 12px;
  cursor: pointer;
  opacity: 0.7;
  transition: all 0.2s ease;
  z-index: 10;
}

.copy-btn:hover {
  opacity: 1;
  background: #2d3748;
  transform: scale(1.05);
}

.copy-btn:active {
  transform: scale(0.95);
}

/* 查找替换面板样式 */
.find-replace-panel {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  background: #ffffff;
  border: 1px solid #e1e8ed;
  border-radius: 0 0 8px 8px;
  max-width: 600px;
  width: calc(100% - 40px);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  z-index: 1001;
  animation: slideDown 0.3s ease-out;
  overflow: hidden;
}

@keyframes slideDown {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #e1e8ed;
  background: #f8f9fa;
  border-radius: 0;
  min-height: 28px;
  overflow: hidden;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
}

.panel-title {
  font-size: 12px;
  font-weight: 500;
  color: #333;
  margin: 0;
  line-height: 1.2;
}

.header-center {
  display: flex;
  align-items: center;
  gap: 8px;
  overflow: hidden;
}

.close-btn {
  background: none;
  border: none;
  font-size: 11px;
  cursor: pointer;
  color: #6c757d;
  border-radius: 4px;
  transition: all 0.2s ease;
}

.close-btn:hover {
  background: #e9ecef;
  color: #495057;
}

.find-replace-content {
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: hidden;
}

.area-selector {
  display: flex;
  align-items: center;
  gap: 12px;
  overflow: hidden;
}

.area-selector label {
  font-size: 12px;
  color: #6c757d;
  font-weight: 500;
}

.radio-group {
  display: flex;
  gap: 16px;
  overflow: hidden;
}

.radio-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #495057;
  cursor: pointer;
}

.radio-item input[type="radio"] {
  margin: 0;
}

.find-input-group,
.replace-input-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.find-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.find-input-group label,
.replace-input-group label {
  font-size: 12px;
  color: #6c757d;
  font-weight: 500;
}

.toggle-replace-btn {
  font-size: 11px;
  color: #666;
  background: none;
  border: 1px solid #ddd;
  padding: 1px 4px;
  border-radius: 3px;
  cursor: pointer;
  transition: all 0.2s;
  line-height: 1.2;
  display: flex;
  align-items: center;
  gap: 4px;
}

.toggle-replace-btn:hover {
  background: #f5f5f5;
  border-color: #999;
}

.input-with-buttons {
  display: flex;
  gap: 8px;
  align-items: center;
  overflow: hidden;
}

.find-input,
.replace-input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  font-size: 12px;
  transition: border-color 0.2s ease;
}

.find-input:focus,
.replace-input:focus {
  outline: none;
  border-color: #4285f4;
  box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.2);
}

.find-buttons,
.replace-buttons {
  display: flex;
  gap: 4px;
  overflow: hidden;
}

.btn-mini {
  background: #4285f4;
  color: white;
  border: none;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 11px;
  cursor: pointer;
  transition: all 0.2s ease;
  white-space: nowrap;
}

.btn-mini:hover:not(:disabled) {
  background: #3367d6;
  transform: translateY(-1px);
}

.btn-mini:disabled {
  background: #e9ecef;
  color: #6c757d;
  cursor: not-allowed;
}

.btn-small {
  background: #6c757d;
  color: white;
  border: none;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 11px;
  cursor: pointer;
  transition: all 0.2s ease;
  white-space: nowrap;
}

.btn-small:hover {
  background: #5a6268;
  transform: translateY(-1px);
}

.match-info {
  font-size: 11px;
  color: #6c757d;
  padding: 4px 0;
}

.find-options {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 8px;
  border-top: 1px solid #e9ecef;
  overflow: hidden;
}

.options-left {
  display: flex;
  gap: 16px;
  overflow: hidden;
}

.checkbox-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #495057;
  cursor: pointer;
}

.checkbox-item input[type="checkbox"] {
  margin: 0;
}

.header-center .checkbox-item {
  gap: 3px;
  font-size: 10px;
  color: #666;
  line-height: 1.2;
}

.header-center .checkbox-item span {
  font-weight: 500;
  min-width: 16px;
  text-align: center;
}

/* 文本区域容器和高亮样式 */
.textarea-container {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  background: white;
  border-radius: 6px;
}

.highlight-overlay {
  position: absolute;
  top: 12px;
  left: 12px;
  right: 12px;
  bottom: 12px;
  pointer-events: none;
  z-index: 3;
  overflow: hidden;
}

.highlight-mark {
  background-color: rgba(255, 255, 0, 0.3);
  border: 1px solid rgba(255, 193, 7, 0.6);
  border-radius: 2px;
  transition: all 0.2s ease;
}

.highlight-mark.current-match {
  background-color: rgba(255, 152, 0, 0.4);
  border-color: rgba(255, 152, 0, 0.8);
  box-shadow: 0 0 4px rgba(255, 152, 0, 0.5);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .content {
    grid-template-columns: 1fr;
  }

  .nginx-format {
    padding: 16px;
  }

  .find-replace-panel {
    top: 0;
    width: calc(100% - 20px);
    max-width: none;
    border-radius: 0 0 6px 6px;
  }

  .find-replace-content {
    padding: 10px 12px;
  }

  .panel-header {
    padding: 3px 6px;
    min-height: 24px;
  }

  .header-left {
    gap: 4px;
  }

  .panel-title {
    font-size: 11px;
  }

  .toggle-replace-btn {
    font-size: 9px;
    padding: 1px 3px;
  }

  .header-center {
    gap: 4px;
  }

  .header-center .checkbox-item {
    font-size: 9px;
    gap: 2px;
  }

  .radio-group {
    flex-direction: column;
    gap: 8px;
  }

  .find-options {
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
  }

  .options-left {
    flex-direction: column;
    gap: 8px;
  }

  .close-btn {
    align-self: flex-end;
  }

  .input-with-buttons {
    flex-direction: column;
    align-items: stretch;
  }

  .find-buttons,
  .replace-buttons {
    justify-content: center;
    margin-top: 8px;
  }

  .find-buttons,
  .replace-buttons {
    justify-content: center;
  }
}
</style>